declare
	--Row count
	a_row_count number;
	--User list
	type a_user_list_type is table of varchar2(26);
	a_user_list a_user_list_type := a_user_list_type();
	--Role list
	type a_role_list_type is table of varchar2(26);
	a_role_list a_role_list_type := a_role_list_type();
	--Current user
	a_curr_user varchar2(26);
begin
	if user = 'SYS' or user = 'SYSTEM' then
		return;
	end if;
	
	--Searching for the user list
	select count(*)  into a_row_count
	from user_objects
	where object_type = 'TABLE' and object_name = 'META_USERS';
	
	--If there is a user list
	if a_row_count > 0 then    
		execute immediate 'select user_name from meta_users'
		bulk collect into a_user_list;
		
	   for i in 1..a_user_list.count loop            
			execute immediate 'drop user ' || a_user_list(i);            
		end loop;
	end if;

	--Searching for the role list
	select count(*)  into a_row_count
	from user_objects
	where object_type = 'TABLE' and object_name = 'META_ROLES';

	--If there is a role list
	if a_row_count > 0 then    
		execute immediate 'select role_name from meta_roles'
		bulk collect into a_role_list;
		
	   for i in 1..a_role_list.count loop            
			execute immediate 'drop role ' || a_role_list(i);            
		end loop;
	end if;
	
	--Dropping the triggers
	for val in (select object_name from user_objects
		where object_type = 'TRIGGER' and generated = 'N' and temporary = 'N') loop
		execute immediate 'drop trigger "' || val.object_name || '"';
	end loop;
	
	--Dropping the functions
	for val in (select object_name from user_objects
		where object_type = 'FUNCTION' and generated = 'N' and temporary = 'N') loop
		execute immediate 'drop function "' || val.object_name || '"';
	end loop;
	
	--Dropping the procedures
	for val in (select object_name from user_objects
		where object_type = 'PROCEDURE' and generated = 'N' and temporary = 'N') loop
		execute immediate 'drop procedure "' || val.object_name || '"';
	end loop;
	
	--Dropping the sequences
	for val in (select object_name from user_objects
		where object_type = 'SEQUENCE' and generated = 'N' and temporary = 'N') loop
		execute immediate 'drop sequence "' || val.object_name || '"';
	end loop;
	
	
	--Dropping the types
	for val in (select object_name from user_objects
		where object_type = 'TYPE' and generated = 'N' and temporary = 'N') loop
		execute immediate 'drop type "' || val.object_name || '"';
	end loop;
	
	--Dropping the views
	for val in (select object_name from user_objects
		where object_type = 'VIEW' and generated = 'N' and temporary = 'N'
		--And it is not a view in a recyclebin
		and object_name not like 'BIN$%') loop
		execute immediate 'drop view "' || val.object_name || '"'
		|| ' cascade constraints';
	end loop;
	
	--Dropping the tables
	for val in (select object_name from user_objects
		where object_type = 'TABLE' and generated = 'N'
		--And it is not a table in a recyclebin
		and object_name not like 'BIN$%') loop
		execute immediate 'drop table "' || val.object_name || '"'
		|| ' cascade constraints';
	end loop;
	
end;